package com.heima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.heima.bean.Category;
import com.heima.bean.Setmeal;
import com.heima.bean.SetmealDish;
import com.heima.common.PageParam;
import com.heima.dao.SetmealDao;
import com.heima.dto.SetmealDto;
import com.heima.exception.CustomException;
import com.heima.service.CategoryService;
import com.heima.service.SetmealDishService;
import com.heima.service.SetmealService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class SetmealServiceImpl implements SetmealService {
    @Autowired
    private SetmealDao setmealDao;

    @Autowired
    private SetmealDishService setmealDishService;

    @Lazy
    @Autowired
    private CategoryService categoryService;

    /**
     * 根据分类的id查询套餐数据
     *
     * @param categoryId
     * @param status
     * @return
     */
    @Override
    public List<Setmeal> findByCategory(Long categoryId, Integer status) {
        //构建条件对象
        LambdaQueryWrapper<Setmeal> lqw = new LambdaQueryWrapper<>();

        //追加条件
        lqw.eq(Setmeal::getCategoryId, categoryId);
        lqw.eq(status != null, Setmeal::getStatus, status);

        //执行查询
        return setmealDao.selectList(lqw);
    }

    /**
     * 增加套餐
     *  1. 添加套餐和其他的添加不一样，因为它要操作两张表： setmeal 套餐表 和 setmeal_dish 套餐菜品表
     *      1.1 先往套餐表加数据
     *
     *      1.2 再往套餐菜品表加数据
     * @param setmealDto
     * @return
     */
    @Override
    public int add(SetmealDto setmealDto) {
        //先往套餐表里面添加数据
        int row = setmealDao.insert(setmealDto);
        if (row > 0) {
            //再往套餐菜品表里面添加数据
            int row2 = 0;
            List<SetmealDish> list = setmealDto.getSetmealDishes();
            for (SetmealDish setmealDish : list) {
                //设置两者之间的主从键之间的联系
                setmealDish.setSetmealId(setmealDto.getId());

                row2 += setmealDishService.add(setmealDish);
            }
            return row2 == list.size() ? 1 : 0;
        }
        return row;
    }

    /**
     * 分页查询套餐
     *
     * @param pageParam
     * @return
     */
    @Override
    public IPage<SetmealDto> page(PageParam pageParam) {
        IPage<Setmeal> page = new Page<>(pageParam.getPage(), pageParam.getPageSize());
        LambdaQueryWrapper<Setmeal> lqw = new LambdaQueryWrapper<>();

        lqw.eq(pageParam.getName() != null, Setmeal::getName, pageParam.getName());
        IPage<Setmeal> setmealIPage = setmealDao.selectPage(page, lqw);

        //遍历每一个套餐
        List<SetmealDto> setmealDtoList = setmealIPage.getRecords().stream().map(setmeal -> {
            // 拿着套餐的分类id去查询分类表，得到分类的数据
            Category category = categoryService.findById(setmeal.getCategoryId());

            //构建SetmealDto
            SetmealDto setmealDto = new SetmealDto();

            //装数据进setmealDto
            BeanUtils.copyProperties(setmeal, setmealDto);
            setmealDto.setCategoryName(category.getName());

            //TODO:: 其实套餐数据，还需要封装该套餐拥有哪些菜品， 这样在更新页面上就可以回显了！

            // 返回setmealDto 意思就是每一个setmeal 就映射出来一个setmealDto
            return setmealDto;
        }).collect(Collectors.toList());

        //构建IPage<SetmealDto>对象
        IPage<SetmealDto> iPage = new Page<>();

        //将数据封装进去
        iPage.setRecords(setmealDtoList);
        iPage.setTotal(setmealIPage.getTotal());

        //返回
        return iPage;
    }

    /**
     * 删除套餐
     *  1. 删除套餐和以前的删除不一样，需要判定，如果套餐属于启售状态，那么禁止删除。
     *      1.1 拿着套餐的id，去查询套餐表，看看是否有套餐属于启售状态！
     *      1.2 如果没有，就可以删除。如果有，就禁止删除！
     *
     * @param ids
     * @return
     */
    @Override
    public int delete(List<Long> ids) {
        //1. 查询这一批id集合里面，是否有套餐属于启售状态！
        // select * from setmeal where id in (1, 3, 5) and status = 1

        LambdaQueryWrapper<Setmeal> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Setmeal::getStatus, 1); //限制状态值为起售
        lqw.in(Setmeal::getId, ids);

        //执行查询
        Long count = setmealDao.selectCount(lqw);

        //如果数量 > 0 禁止它删除
        if(count > 0){
            throw new CustomException("套餐处于启售状态，禁止删除！");
        }
        // 如果程序运行到了这里，即表示套餐属于停售状态，那么直接删除即可
        return setmealDao.deleteBatchIds(ids);
    }
}
